home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / tex / itrns211.zip / SRC / FONT.C < prev    next >
C/C++ Source or Header  |  1991-10-14  |  32KB  |  1,008 lines

  1. /*
  2.  *========================================================================== 
  3.  * Copyright 1991 Avinash Chopde, All Rights Reserved.
  4.  *
  5.  * Permission to use, copy, modify and distribute this software and its
  6.  * documentation for any purpose is hereby granted without fee, provided that
  7.  * the above copyright notice appear in all copies and that both that
  8.  * copyright notice and this permission notice appear in supporting
  9.  * documentation, and that the name of Avinash Chopde not be used in
  10.  * advertising or publicity pertaining to distribution of the software
  11.  * without specific, written prior permission.
  12.  * Avinash Chopde makes no representations about the suitability of this
  13.  * software for any purpose.
  14.  * It is provided "as is" without express or implied warranty.
  15.  *
  16.  * AVINASH CHOPDE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
  17.  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
  18.  * IN NO EVENT SHALL AVINASH CHOPDE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
  19.  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
  20.  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
  21.  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
  22.  * OF THIS SOFTWARE.
  23.  *
  24.  * Author:  Avinash Chopde, 1991
  25.  *        C2 Colonial Drive #4, Andover, MA 01810, USA.
  26.  *
  27.  */
  28.  
  29. #include "itrans.h"
  30. #include "ifm.h"
  31.  
  32. static char S_RCSID[] = "$Header: e:/itrans/src/rcs/font.c 1.11 91/10/14 00:40:13 avinash Exp $";
  33.  
  34. /* definitions used by decode_name() */
  35. #define    ALL_CHARS    -1
  36.     /* ALL_CHARS must be zero-1, see decode_name() */
  37. #define    NO_CHAR        -2
  38.  
  39. /* =================================================================== */
  40. static int S_ccadd(FILE* ifmfp);
  41. static void S_clear_ccadds();
  42. static int S_ccs(FILE* ifmfp, font_t *font);
  43. static int S_cc(FILE* ifmfp, font_t *font);
  44. static int S_prop(FILE* ifmfp, font_t *font);
  45. static int S_fillup_ps(FILE* afmfp, font_t* font);
  46. static int S_fillup_tfm(font_t* font);
  47.  
  48. /* The extra_map[] stores user defined khadi names --
  49.  * these are only used in "same-as" (CCS) IFM tag
  50.  * Cannot be generated directly by the user.
  51.  * See also the definition of G_ifm_map ahead in this file.....
  52.  */
  53. static ifm_enc_t S_ifm_extra_map[NUMEXTRA];
  54.  
  55. /* =================================================================== */
  56. /* initialise font with empty values */
  57. void init_font(font_t* font)
  58. {
  59.     int i, j;
  60.  
  61.     font->prop = UNDEF_FONT;
  62.     font->name[0] = '\0';
  63.     font->fname[0] = '\0';
  64.     font->use_ligatures = TRUE;
  65.  
  66.     for (i = 0; i < NUMKHADI; i ++) {
  67.     font->khadi[i].cus = NULL;
  68.     font->khadi[i].same_as = NULL;
  69.     }
  70.  
  71.     for (i = 0; i < NUMCHARS; i ++) {
  72.         for (j = 0; j < NUMCHARS; j ++) {
  73.         font->ligatures[i][j].cus = NULL;
  74.         font->ligatures[i][j].same_as = NULL;
  75.         }
  76.     }
  77.     for (i = 0; i < 10; i ++) {
  78.     font->digits[i].cus = NULL;
  79.     font->digits[i].same_as = NULL;
  80.     }
  81.  
  82.     for (i = 0; i < NUMPSCHARS; i ++) {
  83.     font->psfm[i].w = 0;
  84.     font->psfm[i].llx = 0;
  85.     font->psfm[i].lly = 0;
  86.     font->psfm[i].urx = 0;
  87.     font->psfm[i].ury = 0;
  88.     }
  89. } /* init_font() */
  90.  
  91. /* =================================================================== */
  92. font_t*    find_font(allfonts_t af, char fname[])
  93. {
  94.     font_t* f;
  95.     int i;
  96.  
  97. #ifdef DEBUG
  98.     fprintf(stderr, "looking for font %s\n", fname);
  99. #endif
  100.  
  101.     f = NULL;
  102.     for (i = 0; i < FONTS_MAX;  i ++) {
  103.  
  104. #ifdef DEBUG
  105.     if (af[i]) fprintf(stderr, "found font %s\n", af[i]->fname);
  106. #endif
  107.  
  108.     if (af[i] && !strcmp(fname, af[i]->fname)) {
  109.        f = af[i];
  110.        break;
  111.     }
  112.     }
  113.     return f;
  114. }
  115. /* =================================================================== */
  116. /* fillup the font data by reading in the IFM file supplied */
  117. /* assumed that init_font() has been called before.... */
  118.  
  119. int fillup_font(font_t* font, char ifmfname[])
  120. {
  121.     int        i;
  122.     char    word[256];
  123.     char    ifmword[256];
  124.     int        ifmtoken;
  125.     char    fmfname[NAMELEN];
  126.     FILE*    fmfp;
  127.     char*    ienv;
  128.     char*    dp;
  129.     FILE*    ifmfp;
  130.     int        errflg= 0;
  131.     
  132.     /* get the search path... */
  133.     ienv = getenv(ITRANS_PATH);
  134.     if (!ienv) {
  135.     putenv(ITRANS_PATH_DEF);
  136.         ienv = getenv(ITRANS_PATH);
  137.     if (!ienv) { /* STUPID ERROR, SYSTEM PROBLEM.. */
  138.         ienv = strchr(ITRANS_PATH_DEF, '=') + 1;
  139.     }
  140.     }
  141.  
  142.     if ( !font ) {
  143.     fprintf(stderr, "Program error (malloc failed ?): fillup_font() got NULL font\n");
  144.     return FALSE;
  145.     }
  146.  
  147.     ifmfp = search_fopen(ienv, ifmfname, "r");
  148.     if (!ifmfp) {
  149.      fprintf(stderr, "Error: could not open %s for reading\n", ifmfname);
  150.      return FALSE;
  151.     }
  152.  
  153.     /* -------- FILLUP khadi */
  154.     /* FILL UP THE DEVNAGARI CHARS */
  155.  
  156.     reset_pifm(); /* reset the IFM parser, set line count to zero etc */
  157.  
  158.     while ( !errflg && (ifmtoken = get_ifm_token(ifmfp, ifmword)) != 0) {
  159.     /* line format is:
  160.        Comment -I- CC <ifm> n ; PCC <pscharnum> <deltax> <deltay> ;
  161.        Comment -I- CCADD <newifmname> ;
  162.        Comment -I- CCS <ifmname> <otherifmname> ;
  163.      */
  164.  
  165.     switch (ifmtoken) {
  166.     case FONT_IFMTAG:
  167.  
  168.         /* example: Comment -I- FONT marathi devnac.afm */
  169.         ifmtoken = get_ifm_token(ifmfp, ifmword);
  170.         if (ifmtoken != DNAME_IFMTAG) {
  171.         fprintf(stderr, "Error in parsing ifm font metrics - expect a fontname after FONT\n");
  172.             errflg++; break;
  173.         }
  174.         strcpy(word, ifmword);
  175.         ifmtoken = get_ifm_token(ifmfp, ifmword);
  176.         if (ifmtoken != DNAME_IFMTAG) {
  177.         fprintf(stderr, "Error in parsing ifm font metrics - expect a filename after FONT %s\n", word);
  178.             errflg++; break;
  179.         }
  180.         strcpy(fmfname, ifmword);
  181.  
  182.         /* strip of path name stuff, and copy */
  183.         dp = strrchr(ifmfname, DIRSEP);
  184.         if (!dp) dp = ifmfname;
  185.         else dp++;
  186.         strcpy(font->fname, dp);
  187.  
  188.         strcpy(font->name, word);
  189.             /* -------- FILLUP ENCODING NAMES */
  190.             /* XXX - fill up font with G_ifm_map - maybe different
  191.          * fonts will use different names for ka, kha, etc!
  192.          * I hope not.
  193.          */
  194.             for (i = 0; i < NUMCHARS; i ++) {
  195.             font->enc[i] = G_ifm_map[i];
  196.             }
  197.  
  198.         /* fill in font Metrics */
  199.         strcpy(word, &ifmword[strlen(ifmword) - 3]); /* get last 3 chars */
  200.         if (!strcmp(word, "afm")) {
  201.         font->prop = TEX_PS_FONT; /* use font for both PostScript
  202.                        * and TeX output
  203.                        */
  204.         } else if (!strcmp(word, "tfm")) {
  205.         font->prop = TEX_FONT; /* use font for TeX output only */
  206.         } else  {
  207.         fprintf(stderr, "font.c::Error: illegal metric file name %s (must end in .afm or .tfm)\n", ifmword);
  208.             errflg++; break;
  209.         }
  210.  
  211.         if (font->prop == TEX_FONT) {
  212.  
  213.         /* dont read in any file, all TeX chars are non-zero
  214.          * widths anyway.
  215.          */
  216.         fmfp = NULL;
  217.         S_fillup_tfm(font);
  218.  
  219.         }  else {
  220.  
  221.         /* fill in PostScript Metrics */
  222.             fmfp = search_fopen(ienv, fmfname, "r");
  223.             if (!fmfp) {
  224.             fprintf(stderr, "font.c::Error: could not open %s for reading (afm)\n", fmfname);
  225.             errflg++; break;
  226.             } 
  227.         S_fillup_ps(fmfp, font);
  228.             fclose(fmfp);
  229.         }
  230.  
  231.         break;
  232.  
  233.     case PROP_IFMTAG:
  234.         if (!S_prop(ifmfp, font)) {
  235.         fprintf(stderr,"**** line %d - illegal PROP line\n", G_ifm_lineno);
  236.             errflg++;
  237.         }
  238.         break;
  239.  
  240.     case CCADD_IFMTAG:
  241.         if (!S_ccadd(ifmfp)) {
  242.         fprintf(stderr,"**** line %d - illegal CCADD line (last token %s)\n",
  243.             G_ifm_lineno, ifmword);
  244.             errflg++;
  245.         }
  246.         break;
  247.  
  248.     case CCS_IFMTAG:
  249.         if (!S_ccs(ifmfp, font)) {
  250.         fprintf(stderr,"**** line %d - illegal CCS line (last token %s)\n",
  251.             G_ifm_lineno, ifmword);
  252.             errflg++;
  253.         }
  254.         break;
  255.     case CC_IFMTAG:
  256.         if (!S_cc(ifmfp, font)) {
  257.         fprintf(stderr,"**** line %d - illegal CC line (last token %s)\n",
  258.             G_ifm_lineno, ifmword);
  259.             errflg++;
  260.         }
  261.         break;
  262.     case COMMENT_IFMTAG:
  263.         break;
  264.     default:
  265.         fprintf(stderr,"**** around line %d (+-1) - warning: unrecognized IFM token %s\n",
  266.             G_ifm_lineno, ifmword);
  267.         if (ifmtoken == PCC_IFMTAG)
  268.             fprintf(stderr,"**** around line %d (+-1) - warning: maybe the CC count is incorrect -- too many PCC's\n",
  269.